﻿//Copyright (c) Microsoft Corporation.  All rights reserved.

using Microsoft.ApplicationServer.Caching;
using System;
using System.Threading;

namespace Microsoft.Ted.Wacel.Cache
{
    public static class DataCacheExtensions
    {
        public static long ReadAndLock(this DataCache cache, string key, long defaultValue, TimeSpan timespan, out DataCacheLockHandle lockHandle, string region)
        {
            for (int i = 0; i < 100; i++)
            {
                try
                {
                    var obj = region == null? cache.Get(key):cache.Get(key, region);
                    if (obj != null)
                    {
                        if (region == null)
                            return (long)cache.GetAndLock(key, timespan, out lockHandle, true);
                        else 
                            return (long)cache.GetAndLock(key, timespan, out lockHandle, region, true);
                    }
                    else
                    {
                        try
                        {
                            if (region == null)
                                cache.Add(key, defaultValue);
                            else 
                                cache.Add(key, defaultValue, region);
                        }
                        catch (DataCacheException dExp)
                        {
                            if (dExp.ErrorCode != DataCacheErrorCode.KeyAlreadyExists)
                                throw;
                            else
                                Thread.Sleep(50);
                        }
                    }
                }
                catch (DataCacheException dExp)
                {
                    if (dExp.ErrorCode != DataCacheErrorCode.ObjectLocked)
                        throw;
                    else
                        Thread.Sleep(50);
                }
            }

            lockHandle = null;
            return defaultValue;
        }
    }
}
